<template>
  <div>
    <!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>权限列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片 -->
    <el-card>
      <el-row >
       <el-col >
         <el-button type="primary">添加角色</el-button>
       </el-col>
    </el-row>
    <!-- 表格 -->
       <el-table
        :data="rolesList"
        stripe
        style="width: 100%" border >
        <el-table-column type="expand">
          <!-- 作用域插槽 组件中用slot标签 通过自定义属性 向父暴露了数据 -->
          <template slot-scope="data">
            <!-- 点击下拉 -->
              <el-row v-for=" (item,index) in data.row.children" :key="item.id" :class="['btnBottm',index == 0 ? 'btnTop' : '']" class="vcenter">
                <!-- 一级下拉菜单 -->
                <el-col :span="5" >
                  <el-tag effect="dark" closable @close="closeTag(item.id,data.row)">{{item.authName}}</el-tag>
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <!-- 二级三级下拉菜单 -->
                <el-col :span="19">
                  <el-row v-for=" (itemm,index) in item.children" :key="itemm.id" :class="[index == 0 ? '' : 'btnTop']"  class="vcenter">
                <!-- 二级下拉菜单 -->
                    <el-col :span="6">
                      <el-tag effect="dark" type="success" closable @close="closeTag(itemm.id,data.row)">{{itemm.authName}}</el-tag>
                      <i class="el-icon-caret-right"></i>
                    </el-col>
                <!-- 三级下拉菜单 -->
                    <el-col :span="18">
                      <el-tag effect="dark" type="warning" v-for="itemmm in itemm.children" :key="itemmm.id" closable @close="closeTag(itemmm.id,data.row)">{{itemmm.authName}}</el-tag>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>
          </template>
        </el-table-column>
        <el-table-column prop="id" abel="#" type="index" align="center"></el-table-column>
        <el-table-column
          prop="roleName"
          label="角色名称" align="center"
          >
        </el-table-column>
        <el-table-column
          prop="roleDesc"
          label="角色描述" align="center">
        </el-table-column>
      <el-table-column
        label="操作" align="center">
        el-table-column
        prop="mg_state"
        label="操作">
        <template slot-scope="data">
        <div class="bt">
          <el-button type="primary" size="mini"  icon="el-icon-edit"  @click="index(data.row.id)">编辑</el-button>
        <el-button type="danger"   size="mini"  icon="el-icon-delete"  @click="del(data.row.id)">删除</el-button>
          <el-button type="warning"  size="mini" icon="el-icon-setting" @click="set(data.row)">分配权限</el-button>
        </div>
        </template>
      </el-table-column>
      </el-table>
    </el-card>
    <!-- 分配权限对话框 树形checkbox -->
    <el-dialog
        title="分配权限"
        :visible.sync="setDialogVisible"
        width="50%" @close="closeTree">
        <el-tree :data="rightsList" :props="defaultProps" show-checkbox default-expand-all node-key="id" :default-checked-keys="defKeys" ref="treeRef"></el-tree>
        <!-- :default-checked-keys 默认要展示选中的节点
         :data="rightsList" 要展示的数据集合
         :props 展示选择框的内容和数据集合结合
         -->
        <span slot="footer" class="dialog-footer">
          <el-button @click="setDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="allotRights">确 定</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data () {
    return {
      rolesList: [], // 角色列表
      rightsList: [], // 角色权限树形
      setDialogVisible: false, // 分配权限弹出框
      defaultProps: { // 控制树形，展示数组中的那些属性
        label: 'authName', // 指定节点标签为节点对象的某个属性值
        children: 'children' // 指定子树为节点对象的某个属性值
      },
      defKeys: [], // 显示默认展示的那些节点，由递归遍历rightsList的三级节点
      nodeId: 0
    }
  },
  created () {
    this.getRolesList()
  },
  methods: {
    async getRolesList () { // 获取角色权限
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.rolesList = res.data
    },
    closeTag (rightId, role) { // 删除tag标签
      this.open(rightId, role)
    },
    async open (rightId, role) { // 删除下拉框中的TAG标签的提示框
      const data = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).catch(res => res) // 通过catch捕获错误并且返回res
      if (data === 'cancel') return
      this.delTag(rightId, role)
    },
    async delTag (rightId, role) { // 删除下拉框中的TAG标签url
      const { data: res } = await this.$http.delete('roles/' + role.id + '/rights/' + rightId)
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message({ message: res.meta.msg, type: 'success' })
      role.children = res.data
    },
    set (node) { // 分配权限按钮
      this.nodeId = node.id // 将当前的Id保存下来
      this.setDialogVisible = true
      this.getRightList()
      this.getSonKey(node, this.defKeys) // 递归获取当前三级节点默认展示
    },
    async getRightList () { // 获取树形 角色权限url请求
      const { data: res } = await this.$http.get('rights/tree')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.rightsList = res.data
    },
    getSonKey (node, arr) { // 递归函数 遍历三级id，作为展示的选中选项
      if (!node.children) { // 如果没有子节点代表为三级
        return arr.push(node.id)
      }
      node.children.forEach(item => { // 遍历子节点递归
        this.getSonKey(item, arr)
      })
    },
    closeTree () { // 关闭弹窗 解决重复添加ID BUG
      this.defKeys = [] // 将默认选中展示的置为空
    },
    async allotRights () { // 点击树形中的确定按钮 提交修改后的选项id
      const keys = [...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys()] // 通过组件对象的方法，得到选中和半选中的id
      const str = keys.join(',') // 转化为字符串
      const { data: res } = await this.$http.post('roles/' + this.nodeId + '/rights', { rids: str }) // 调用接口发送
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message({ message: res.meta.msg, type: 'success' })
      this.setDialogVisible = false
      this.getRolesList()
    }
  }
}
</script>

<style lang="less" scoped>
.btnTop {
  border-top: 1px solid #ccc;
}
.btnBottm {
  border-bottom:1px solid #ccc ;
}
.el-tag {
  margin: 10px;
}
.vcenter {
  display: flex;
  align-items: center;
}
</style>
